/******************************************************************************* 
 * Copyright (C) 2012-2015 Microfountain Technology, Inc. All Rights Reserved. 
 * 
 * Unauthorized copying of this file, via any medium is strictly prohibited.   
 * Proprietary and confidential
 * 
 * Last Modified: 2015-9-22 17:46:29
 ******************************************************************************/
package cn.cmcc.online.smsapi.sdk.util;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.zip.ZipException;

import cn.cmcc.online.smsapi.sdk.Iservice.OnlineUpdateCycleConfigInterface;
import cn.cmcc.online.smsapi.sdk.constant.Constant;
import cn.cmcc.online.smsapi.sdk.db.entity.Resdownload;
import cn.cmcc.online.smsapi.sdk.db.entity.ResdownloadManager;
import cn.cmcc.online.smsapi.sdk.dex.DexUtil;
import cn.cmcc.online.smsapi.sdk.log.LogManager;
import cn.cmcc.online.smsapi.sdk.net.HttpConnection;
import cn.cmcc.online.smsapi.sdk.net.NetUtil;

/**
 * 资源下载对列
 * 
 * @author Administrator
 * 
 */
public class ZipPackageDownloaderQueue extends Thread {

    int retryTime = 0;
    public static boolean isdownloadNotWifi = false;
    Resdownload resdownload;// 当前正在下载的数据
    static HashSet<String> needPriorDownUrl = new HashSet<String>();// 需要优先下载的数据
    static boolean isRun = false;// 是否正在下载中

    /**
     * 添加需要优先下载的数据
     * 
     * @param url
     */
    public synchronized static void addNeedPriorDownUrlData(String url) {

        if (!StringUtils.isNull(url) && !needPriorDownUrl.contains(url)) {

            needPriorDownUrl.add(url);
        }

    }

    /**
     * 移除需要优先下载的数据
     * 
     * @param url
     */
    public synchronized static void removeNeedPriorDownUrlData(String url) {
        needPriorDownUrl.remove(url);
    }

    /**
     * 获取一个需要优先下载的数据
     * 
     * @param url
     * @return
     */
    public synchronized static Resdownload getNeedPriorDownUrlData() {
        Iterator<String> it = needPriorDownUrl.iterator();
        Resdownload res = null;
        ArrayList<String> list = new ArrayList<String>();
        while (it != null && it.hasNext()) {
            String url = it.next();
            res = ResdownloadManager.getNeedPriorDownUrlData(url);
            list.add(url);
            if (res != null) {
                break;
            }
        }
        // 移除目前不需要再下载的.
        needPriorDownUrl.removeAll(list);
        list.clear();
        return res;
    }

    /**
     * 获取下一个需要下载的资源
     * 
     * @return
     */
    public synchronized static Resdownload getNextNeedDownResdownload() {
        // 先查看是否有需要优先下载的数据
        Resdownload res = null;
        // 获取需要优先下载的
        res = getNeedPriorDownUrlData();
        if (res == null) {
            // 获取未下载完的,且一天之内未下载过的资源
            res = ResdownloadManager.getOneNotFinishDownload();
        }
        return res;
    }

    private ZipPackageDownloaderQueue(boolean isdownloadNotWifi) {

        // this.isdownloadNotWifi = isdownloadNotWifi;
        // ResdownloadManager.updateLoadTime(resdownload);
    }

    /**
     * 执行下载资源队列线程
     * 
     * @param isdownloadNotWifi
     */
    public synchronized static void runDownResQueue(boolean isdownloadNotWifi) {
        if (isRun == false) {
            // 当队列线程序未运行时,才运行
            ZipPackageDownloaderQueue queue = new ZipPackageDownloaderQueue(isdownloadNotWifi);
            queue.start();
        }
    }

    synchronized static void setRun(boolean run) {
        isRun = run;
    }

    @Override
    public void run() {
    	try {
    		if (isRun == false) {
                // isRun = true;
                setRun(true);
                try {
                    Thread.sleep(3000);
                } catch (Throwable e) {
//                    e.printStackTrace();
                    LogManager.e(Constant.TAG, "run: ", e);

                }
                Resdownload resdownload = getNextNeedDownResdownload();
                downLoadRes(resdownload);
                // isRun = false;
                setRun(false);
            }
		} catch (Throwable e) {
            LogManager.e(Constant.TAG, "run: ", e);
		}
        
    }

    /***
     * 下载资源
     * 
     * @param resdownload
     */
    private void downLoadRes(Resdownload resdownload) {
        if (!NetUtil.checkAccessNetWork(2)) {
            return;
        }
        if (resdownload != null) {
            try {
                this.resdownload = resdownload;
                downloadzippackage(resdownload);
            } catch (Throwable e) {
//                e.printStackTrace();
                LogManager.e(Constant.TAG, "downLoadRes: ", e);

            } finally {

                try {
                    Thread.sleep(2000);
                } catch (Throwable e) {
//                    e.printStackTrace();
                    LogManager.e(Constant.TAG, "downLoadRes: ", e);

                }
                downLoadRes(getNextNeedDownResdownload());
            }
        } else {
            isRun = false;
        }
    }

    public void downloadzippackage(Resdownload zippackage) {
        File saveFilePath = null;
        File filePath = new File(getTempZipFolder() + File.separator);
        if (!filePath.exists()) {
            filePath.mkdirs();
        }
        saveFilePath = new File(filePath, getZipName(zippackage));
        if (saveFilePath.exists()) {
            saveFilePath.delete();
        }

        if (LogManager.debug) {
//            LogManager.d("ZipPackageDownloaderQueue", "下载时间=" + new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(System.currentTimeMillis()) + " 下载url=" + NetUtil.prex + zippackage.url + " scene_id=" + resdownload.scene_id + " id=" + resdownload.id);
        }

        boolean downSucc = false;

        while (retryTime < Constant.RETRY_TIME && !downSucc) {
            try {
                String dUrl = NetUtil.prex + zippackage.url;
                downSucc = downloadFileUseOneUrl(dUrl, saveFilePath);
            } catch (Throwable e) {
            }
            /* SDK-519 huangzhiqiang 20160705 start */
            retryTime++;
            /* SDK-519 huangzhiqiang 20160705 end */
            try {
                Thread.sleep(4000 * retryTime);
            } catch (InterruptedException e) {
                LogManager.e(Constant.TAG, "downloadzippackage: ", e);
            }
        }

//        PrintTestLogUtil.printTestLog("ZipPackageDownloaderQueue", "downSuc =" + downSucc);

        if (downSucc) {
            try {
                XyUtil.upZipFile(saveFilePath, Constant.getDRAWBLE_PATH());
                ResdownloadManager.updateResdownloadStatus(resdownload.id, ResdownloadManager.FINISH, resdownload.url);
                FileUtils.deleteAllFile(saveFilePath);
            } catch (ZipException e) {
                LogManager.e(Constant.TAG, "downloadzippackage: ", e);
                FileUtils.deleteAllFile(saveFilePath);
                // ResdownloadManager.updateResdownloadStatus(resdownload.id,
                // 0,ResdownloadManager.NOTFINISH);
            } catch (IOException e) {
                LogManager.e(Constant.TAG, "downloadzippackage: ", e);
                FileUtils.deleteAllFile(saveFilePath);
                // ResdownloadManager.updateResdownloadStatus(resdownload.id,
                // 0,ResdownloadManager.NOTFINISH);
            } catch (Throwable e) {
//                e.printStackTrace();
                LogManager.e(Constant.TAG, "downloadzippackage: " , e);
                FileUtils.deleteAllFile(saveFilePath);
            }
        } else {
            // ResdownloadManager.updateResdownloadStatus(resdownload.id,
            // 0,ResdownloadManager.NOTFINISH);
        }
    }

    public boolean downloadFileUseOneUrl(String downloadUrl, File saveFilePath) throws Throwable {

        RandomAccessFile threadfile = null;
        InputStream inStream = null;
        HttpURLConnection http = null;
        long fileSize = 0;
        try {
            if (!StringUtils.isNull(downloadUrl)) {
                if (downloadUrl.startsWith("https") || downloadUrl.startsWith("HTTPS")) {
                    http = HttpConnection.createHttpsURLConnectionAndConnect(downloadUrl);
                } else {
                    URL downUrl = new URL(NetUtil.getUrlWithPara(downloadUrl));
                    http = (HttpURLConnection) downUrl.openConnection();
                    http.setConnectTimeout(5000);
                    /* SDK-534 huangzhiqiang 20160712 start */
                    http.setReadTimeout(90000);
                    /* SDK-534 huangzhiqiang 20160712 end */
                    http.setRequestMethod("GET");
                    http.addRequestProperty("clientKey", "360_c");
                    http.addRequestProperty("reqVersion", "5.2.2.1015");
                    http.connect();
                    if (LogManager.debug) {
//                        LogManager.d("ZipPackageDownloaderQueue", "downUrl =" + downUrl);
                    }
                }
            }

            long range = 0;

            if (http == null) {
                return false;
            }
            int responseCode = 0;
            responseCode = http.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_PARTIAL) {
                fileSize = http.getContentLength();

                if (LogManager.debug) {
//                    LogManager.d("ZipPackageDownloaderQueue", " fileSize" + fileSize);

                }
                if (fileSize == 0) {// 文件大小为0
                                    // 文件大小为0.不再重试
                    if (resdownload != null) {
                        ResdownloadManager.updateLoadTime(resdownload, System.currentTimeMillis() + DexUtil.getUpdateCycleByType(OnlineUpdateCycleConfigInterface.TYPE_LAST_LOAD_TIME_ADD, 24 * 3600 * 1000));
                    }
                    FileUtils.deleteAllFile(saveFilePath);
                    retryTime = 4;
                    return false;

                }

                inStream = http.getInputStream();
                byte[] buffer = new byte[1024];
                int offset = 0;
                threadfile = new RandomAccessFile(saveFilePath, "rwd");
                if (inStream!=null && threadfile!=null) {
                    threadfile.seek(range);
                    while ((offset = inStream.read(buffer)) != -1) {
                        threadfile.write(buffer, 0, offset);
                    }	
				}
            } else if (responseCode == 404) {
                // 404错误.不再重试
                if (resdownload != null) {
                    ResdownloadManager.updateLoadTime(resdownload, System.currentTimeMillis() + DexUtil.getUpdateCycleByType(OnlineUpdateCycleConfigInterface.TYPE_LAST_LOAD_TIME_ADD, 24 * 3600 * 1000));
                }
                FileUtils.deleteAllFile(saveFilePath);
                retryTime = 4;
                return false;
            } else {
                return false;
            }
        } catch (Throwable e) {

            throw e;
        } finally {
            if (threadfile != null) {
                try {
                    threadfile.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
//                    e.printStackTrace();
                    LogManager.e(Constant.TAG, "downloadFileUseOneUrl: ", e);

                }
            }
            if (inStream != null) {
                try {
                    inStream.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
//                    e.printStackTrace();
                    LogManager.e(Constant.TAG, "downloadFileUseOneUrl: ", e);

                }
            }
            if (http != null) {
                try {
                    http.disconnect();
                    http = null;
                } catch (Throwable e) {
//                    e2.printStackTrace();
                    LogManager.e(Constant.TAG, "downloadFileUseOneUrl: ", e);

                }

            }

            /* SDK-573 huangzhiqinag 20160801 start */
//            System.gc();
            /* SDK-573 huangzhiqinag 20160801 end */
        }
        if (LogManager.debug) {
//            LogManager.ll("netflows_used", "下载了 downloadUrl=" + downloadUrl + " fileSize=" + fileSize);
        }
        return true;

    }


    public static String getTempZipFolder() {

        String folder = Constant.getFilePath() + "ziptemp";
        return folder;
    }

    public static String getZipName(Resdownload resdownload) {
        String url = resdownload.url;
        String filename = url.substring(url.lastIndexOf('/') + 1);
        return filename;
    }

}
